﻿using System;
using System.Collections.Generic;
using System.Text;

namespace SweetSQL.Data
{
    /// <summary>
    /// Class that maps a class to a database table
    /// </summary>
    /// <typeparam name="T">Type to map</typeparam>
    public class Table<T> : IEnumerable<T>
        where T : class, new()
    {
        internal IDatabase Database = null;
        internal TableInfo TableInfo = null;

        internal Table()
        { }

        /// <summary>
        /// Inserts a row
        /// </summary>
        /// <param name="instance">Instance to insert</param>
        public void Insert(T instance)
        {
            Database.Insert(this, instance);
        }

        /// <summary>
        /// Bulk inserts many rows, with a single IDbCommand
        /// </summary>
        /// <param name="enumerable">Enumerable list to insert</param>
        public void BulkInsert(IEnumerable<T> enumerable)
        {
            Database.BulkInsert(this, enumerable);
        }

        /// <summary>
        /// Updates a row by primary key
        /// </summary>
        /// <param name="instance">Instance containing data to update with</param>
        /// <returns>Rows affected</returns>
        public int Update(T instance)
        {
            return Database.Update(this, instance);
        }

        /// <summary>
        /// Deletes all rows from table
        /// </summary>
        /// <returns>Rows affected</returns>
        public int Delete()
        {
            return Database.Delete(this);
        }

        /// <summary>
        /// Deletes a row by its primary key
        /// </summary>
        /// <param name="instance">Instance with valid primary key</param>
        /// <returns>Rows affected</returns>
        public int Delete(T instance)
        {
            return Database.Delete(this, instance);
        }

        /// <summary>
        /// Selects all rows
        /// </summary>
        /// <returns>Result set</returns>
        public IEnumerable<T> Select()
        {
            return Database.Select(this);
        }

        /// <summary>
        /// Selects one row by primary key
        /// </summary>
        /// <param name="instance">Instance with valid primary key</param>
        /// <returns>Complete row, or null if not found</returns>
        public T Select(T instance)
        {
            return Database.Select(this, instance);
        }

        /// <summary>
        /// Drops table
        /// </summary>
        /// <returns>Rows affected</returns>
        public int Drop()
        {
            return Database.Drop(this);
        }

        /// <summary>
        /// Creates table
        /// </summary>
        /// <returns>Rows affected</returns>
        public int Create()
        {
            return Database.Create(this);
        }

        /// <summary>
        /// Executes raw query with result set
        /// </summary>
        /// <param name="rawQuery">Raw query instance</param>
        /// <returns>Result set</returns>
        public IEnumerable<T> ExecuteReader(RawQuery rawQuery)
        {
            return Database.ExecuteReader(this, rawQuery);
        }

        /// <summary>
        /// Executes raw query
        /// </summary>
        /// <param name="rawQuery">Raw query instance</param>
        /// <returns>Rows affected</returns>
        public int ExecuteNonQuery(RawQuery rawQuery)
        {
            return Database.ExecuteNonQuery(this, rawQuery);
        }

        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
            return Select().GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return Select().GetEnumerator();
        }
    }
}
